package org.zjx.file;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.*;

public class FileUtil implements FileOperations {

    //-------------------------- 基础文件操作 --------------------------//

    @Override
    public boolean exists(String path) {
        return new File(path).exists();
    }

    @Override
    public boolean createNewFile(String path) throws IOException {
        File file = new File(path);
        if (file.exists()) return false;
        return file.createNewFile();
    }

    @Override
    public long getFileSize(String path) {
        return new File(path).length();
    }

    @Override
    public long getLastModifiedTime(String path) {
        return new File(path).lastModified();
    }

    @Override
    public void delete(String path) {
        File file = new File(path);
        if (file.exists()) file.delete();
    }

    //-------------------------- 内容读写操作 --------------------------//

    @Override
    public void writeBytes(String path, byte[] content) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(path)) {
            fos.write(content);
        }
    }

    @Override
    public void writeText(String path, String content) throws IOException {
        Files.write(Paths.get(path), content.getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public byte[] readBytes(String path) throws IOException {
        return Files.readAllBytes(Paths.get(path));
    }

    @Override
    public String readText(String path) throws IOException {
        return new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
    }

    //-------------------------- 文件信息获取 --------------------------//

    @Override
    public String getFileNameWithExtension(String path) {
        return Paths.get(path).getFileName().toString();
    }

    @Override
    public String getFileNameWithoutExtension(String path) {
        String fileName = getFileNameWithExtension(path);
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
    }

    @Override
    public String getFileExtension(String path) {
        String fileName = getFileNameWithExtension(path);
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
    }

    //-------------------------- 目录操作 --------------------------//

    @Override
    public List<File> listFiles(String dirPath, String... extensions) {
        File dir = new File(dirPath);
        if (!dir.isDirectory()) return Collections.emptyList();

        return Arrays.asList(Objects.requireNonNull(dir.listFiles((d, name) -> {
            if (extensions.length == 0) return true;
            String fileExt = name.substring(name.lastIndexOf('.') + 1);
            return Arrays.asList(extensions).contains(fileExt);
        })));
    }

    @Override
    public List<String> getAllFilePaths(String dirPath) {
        List<String> paths = new ArrayList<>();
        File dir = new File(dirPath);
        if (!dir.exists()) return paths;

        File[] files = dir.listFiles();
        if (files == null) return paths;

        for (File file : files) {
            if (file.isDirectory()) {
                paths.addAll(getAllFilePaths(file.getAbsolutePath()));
            } else {
                paths.add(file.getAbsolutePath());
            }
        }
        return paths;
    }

    //-------------------------- 特殊文件类型处理 --------------------------//

    public BufferedImage readImage(String path) throws IOException {
        BufferedImage image = ImageIO.read(new File(path));
        // 创建一个新的 BufferedImage，类型为 TYPE_INT_ARGB，用于支持透明度
        BufferedImage argbImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);

        // 使用 Graphics2D 将 TYPE_INT_RGB 图像的像素数据绘制到新的 TYPE_INT_ARGB 图像上
        Graphics2D g2d = argbImage.createGraphics();
        g2d.drawImage(image, 0, 0, null);
        g2d.dispose();

        return argbImage;
    }

    public void writeImage(BufferedImage image, String formatName, String outputPath) throws IOException {
        ImageIO.write(image, formatName, new File(outputPath));
    }
}
